package com.ishare.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.beans.BeanMap;

import java.lang.reflect.Field;
import java.util.Map;

/***
 * @desc 基于CGlib，扩展BeanUtils 对复杂类型的CGlib更有优势
 */
public class BeanUtils extends org.springframework.beans.BeanUtils {
    private final static Logger log = LoggerFactory.getLogger(BeanUtils.class);

    protected BeanUtils() {

    }

    /**
     * 实例化对象
     *
     * @param clazz 类
     * @return 对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T newInstance(Class<?> clazz) {
        try {
            return (T) clazz.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 实例化对象
     *
     * @param clazzStr 类名
     * @return {T}
     */
    public static <T> T newInstance(String clazzStr) {
        try {
            Class<?> clazz = Class.forName(clazzStr);
            return newInstance(clazz);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * copy 对象属性到另一个对象，默认不使用Convert
     *
     * @param clazz 类名
     * @return {T}
     */
    public static <T> T copy(Object src, Class<T> clazz) {
        BeanCopier copier = BeanCopier.create(src.getClass(), clazz, false);
        T to = newInstance(clazz);
        copier.copy(src, to, null);
        return to;
    }

    /**
     * 拷贝对象
     *
     * @param src  源对象
     * @param dist 需要赋值的对象
     */
    public static void copy(Object src, Object dist) {
        BeanCopier copier = BeanCopier.create(src.getClass(), dist.getClass(), false);
        copier.copy(src, dist, null);
    }

    /**
     * 将对象装成map形式 注意：生成的是unmodifiableMap
     *
     * @param src 源对象
     * @return {Map<K, V>}
     */
    @SuppressWarnings("unchecked")
    public static <K, V> Map<K, V> toMap(Object src) {
        return BeanMap.create(src);
    }


    /**
     * 单个对象的某个键的值
     *
     * @param obj 对象
     * @param key 键
     * @return Object 键在对象中所对应得值 没有查到时返回空字符串
     */
    public static Object getValueByKey(Object obj, String key) {
        // 得到类对象
        Class userCla = (Class) obj.getClass();
        //得到类中的所有属性集合
        Field[] fs = userCla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            // 设置些属性是可以访问的
            f.setAccessible(true);
            try {

                if (f.getName().endsWith(key)) {
                    return f.get(obj);
                }
            } catch (IllegalArgumentException e) {
                log.error("BeanUtils getValueByKey IllegalArgumentException Error" + e);
            } catch (IllegalAccessException e) {
                log.error("BeanUtils getValueByKey IllegalAccessException Error" + e);
            }
        }
        // 没有查到时返回空字符串
        return "";
    }

}
